using AutoMapper;
using StudentManagement.Application.DTOs;
using StudentManagement.Domain.Entities;
using StudentManagement.Domain.Repositories;

namespace StudentManagement.Application.Services;

public class CourseService : ICourseService
{
    private readonly ICourseRepository _courseRepository;
    private readonly IClassRepository _classRepository;
    private readonly IScoreRepository _scoreRepository;
    private readonly IMapper _mapper;

    public CourseService(ICourseRepository courseRepository, IClassRepository classRepository, IScoreRepository scoreRepository, IMapper mapper)
    {
        _courseRepository = courseRepository;
        _classRepository = classRepository;
        _scoreRepository = scoreRepository;
        _mapper = mapper;
    }

    public async Task<CourseDTO> GetCourseByIdAsync(int id)
    {
        var course = await _courseRepository.GetByIdAsync(id);
        if (course == null)
        {
            throw new Exception("课程不存在");
        }

        var courseDTO = _mapper.Map<CourseDTO>(course);
        var classInfo = await _classRepository.GetByIdAsync(course.ClassId);
        if (classInfo != null)
        {
            courseDTO.ClassName = classInfo.ClassName;
        }

        return courseDTO;
    }

    public async Task<CourseDTO> GetCourseByCodeAsync(string courseCode)
    {
        var course = await _courseRepository.GetCourseByCodeAsync(courseCode);
        if (course == null)
        {
            throw new Exception("课程不存在");
        }

        var courseDTO = _mapper.Map<CourseDTO>(course);
        var classInfo = await _classRepository.GetByIdAsync(course.ClassId);
        if (classInfo != null)
        {
            courseDTO.ClassName = classInfo.ClassName;
        }

        return courseDTO;
    }

    public async Task<IEnumerable<CourseDTO>> GetAllCoursesAsync()
    {
        var courses = await _courseRepository.GetAllAsync();
        var courseDTOs = _mapper.Map<IEnumerable<CourseDTO>>(courses);
        
        // 为每个课程添加班级名称
        foreach (var courseDTO in courseDTOs)
        {
            var classInfo = await _classRepository.GetByIdAsync(courseDTO.ClassId);
            if (classInfo != null)
            {
                courseDTO.ClassName = classInfo.ClassName;
            }
        }

        return courseDTOs;
    }

    public async Task<IEnumerable<CourseDTO>> GetCoursesByClassIdAsync(int classId)
    {
        var courses = await _courseRepository.GetCoursesByClassIdAsync(classId);
        var courseDTOs = _mapper.Map<IEnumerable<CourseDTO>>(courses);
        
        // 添加班级名称
        var classInfo = await _classRepository.GetByIdAsync(classId);
        if (classInfo != null)
        {
            foreach (var courseDTO in courseDTOs)
            {
                courseDTO.ClassName = classInfo.ClassName;
            }
        }

        return courseDTOs;
    }

    public async Task<IEnumerable<CourseDTO>> SearchCoursesAsync(string keyword)
    {
        var courses = await _courseRepository.SearchCoursesAsync(keyword);
        var courseDTOs = _mapper.Map<IEnumerable<CourseDTO>>(courses);
        
        // 为每个课程添加班级名称
        foreach (var courseDTO in courseDTOs)
        {
            var classInfo = await _classRepository.GetByIdAsync(courseDTO.ClassId);
            if (classInfo != null)
            {
                courseDTO.ClassName = classInfo.ClassName;
            }
        }

        return courseDTOs;
    }

    public async Task<CourseDTO> CreateCourseAsync(CourseDTO courseDTO)
    {
        // 验证班级是否存在
        if (!await _classRepository.ExistsAsync(courseDTO.ClassId))
        {
            throw new Exception("班级不存在");
        }

        // 验证课程代码是否已存在
        var existingCourse = await _courseRepository.GetCourseByCodeAsync(courseDTO.CourseCode);
        if (existingCourse != null)
        {
            throw new Exception("课程代码已存在");
        }

        var course = _mapper.Map<Course>(courseDTO);
        await _courseRepository.AddAsync(course);

        var createdCourseDTO = _mapper.Map<CourseDTO>(course);
        var classInfo = await _classRepository.GetByIdAsync(course.ClassId);
        createdCourseDTO.ClassName = classInfo?.ClassName;

        return createdCourseDTO;
    }

    public async Task<CourseDTO> UpdateCourseAsync(int id, CourseDTO courseDTO)
    {
        var existingCourse = await _courseRepository.GetByIdAsync(id);
        if (existingCourse == null)
        {
            throw new Exception("课程不存在");
        }

        // 验证班级是否存在
        if (!await _classRepository.ExistsAsync(courseDTO.ClassId))
        {
            throw new Exception("班级不存在");
        }

        // 验证课程代码是否已被其他课程使用
        var courseWithSameCode = await _courseRepository.GetCourseByCodeAsync(courseDTO.CourseCode);
        if (courseWithSameCode != null && courseWithSameCode.Id != id)
        {
            throw new Exception("课程代码已被其他课程使用");
        }

        // 更新课程信息
        _mapper.Map(courseDTO, existingCourse);
        await _courseRepository.UpdateAsync(existingCourse);

        var updatedCourseDTO = _mapper.Map<CourseDTO>(existingCourse);
        var classInfo = await _classRepository.GetByIdAsync(existingCourse.ClassId);
        updatedCourseDTO.ClassName = classInfo?.ClassName;

        return updatedCourseDTO;
    }

    public async Task DeleteCourseAsync(int id)
    {
        var course = await _courseRepository.GetByIdAsync(id);
        if (course == null)
        {
            throw new Exception("课程不存在");
        }

        // 删除相关的成绩记录
        var scores = await _scoreRepository.GetScoresByCourseIdAsync(id);
        foreach (var score in scores)
        {
            await _scoreRepository.DeleteAsync(score.Id);
        }

        await _courseRepository.DeleteAsync(id);
    }

    public async Task<bool> CourseExistsAsync(int id)
    {
        return await _courseRepository.ExistsAsync(id);
    }

    public async Task<bool> CourseCodeExistsAsync(string courseCode)
    {
        var course = await _courseRepository.GetCourseByCodeAsync(courseCode);
        return course != null;
    }

    // 由于Course实体没有TeacherId字段，但有TeacherName字段，
    // 这里假设TeacherId实际上是指教师姓名，并通过TeacherName来查找课程
    public async Task<IEnumerable<CourseDTO>> GetCoursesByTeacherIdAsync(int teacherId)
    {
        // 获取所有课程
        var allCourses = await _courseRepository.GetAllAsync();
        
        // 过滤出TeacherName包含teacherId的课程（这里假设teacherId是教师姓名的一部分）
        var teacherCourses = allCourses.Where(c => c.TeacherName != null && c.TeacherName.Contains(teacherId.ToString())).ToList();
        
        var courseDTOs = _mapper.Map<IEnumerable<CourseDTO>>(teacherCourses);
        
        // 为每个课程添加班级名称
        foreach (var courseDTO in courseDTOs)
        {
            var classInfo = await _classRepository.GetByIdAsync(courseDTO.ClassId);
            if (classInfo != null)
            {
                courseDTO.ClassName = classInfo.ClassName;
            }
        }
        
        return courseDTOs;
    }
}